﻿Imports System
Imports System.Collections
Imports System.Collections.Generic
Imports System.ComponentModel.Design
Imports System.Drawing
Imports System.Windows.Forms
Imports System.Workflow.ComponentModel

Namespace System.Workflow.ComponentModel.Design
    Friend NotInheritable Class WindowManager
        Inherits WorkflowDesignerMessageFilter
        ' Methods
        Friend Sub New()
        End Sub

        Private Function GetDesignerWithFocus() As ActivityDesigner
            Dim designer As ActivityDesigner = Nothing
            Dim service As ISelectionService = [TryCast](MyBase.GetService(GetType(ISelectionService)),ISelectionService)
            If (service Is Nothing) Then
                Return designer
            End If
            Dim primarySelection As Object = service.PrimarySelection
            If TypeOf primarySelection Is Activity Then
                Return ActivityDesigner.GetDesigner([TryCast](primarySelection,Activity))
            End If
            Return ActivityDesigner.GetParentDesigner(primarySelection)
        End Function

        Protected Overrides Function OnDragEnter(ByVal eventArgs As DragEventArgs) As Boolean
            If (Not Me.currentActiveDesigner Is Nothing) Then
                DirectCast(Me.currentActiveDesigner, IWorkflowDesignerMessageSink).OnMouseLeave
                Me.currentActiveDesigner = Nothing
            End If
            Return False
        End Function

        Protected Overrides Function OnKeyDown(ByVal eventArgs As KeyEventArgs) As Boolean
            If ((Not eventArgs Is Nothing) AndAlso ((eventArgs.KeyCode = Keys.Prior) OrElse (eventArgs.KeyCode = Keys.Next))) Then
                Me.UpdateViewOnPageUpDown((eventArgs.KeyCode = Keys.Prior))
            End If
            Dim service As ISelectionService = [TryCast](DirectCast(MyBase.ParentView, IServiceProvider).GetService(GetType(ISelectionService)),ISelectionService)
            If (eventArgs.KeyCode = Keys.Return) Then
                Dim designer As IDesigner = ActivityDesigner.GetDesigner([TryCast](service.PrimarySelection,Activity))
                If (Not designer Is Nothing) Then
                    designer.DoDefaultAction
                    eventArgs.Handled = True
                End If
            ElseIf (eventArgs.KeyCode = Keys.Escape) Then
                If Not eventArgs.Handled Then
                    Dim parentDesigner As CompositeActivityDesigner = ActivityDesigner.GetParentDesigner(service.PrimarySelection)
                    If (Not parentDesigner Is Nothing) Then
                        service.SetSelectedComponents(New Object() { parentDesigner.Activity }, SelectionTypes.Replace)
                    End If
                    eventArgs.Handled = True
                End If
            ElseIf (eventArgs.KeyCode = Keys.Delete) Then
                Dim host As IDesignerHost = [TryCast](DirectCast(MyBase.ParentView, IServiceProvider).GetService(GetType(IDesignerHost)),IDesignerHost)
                If ((Not host Is Nothing) AndAlso Not service.GetComponentSelected(host.RootComponent)) Then
                    Dim selectedComponents As ICollection = service.GetSelectedComponents
                    If DesignerHelpers.AreComponentsRemovable(selectedComponents) Then
                        Dim activities As New List([Of] Activity)(Helpers.GetTopLevelActivities(service.GetSelectedComponents))
                        Dim flag As Boolean = (activities.Count > 0)
                        Dim entry As DictionaryEntry
                        For Each entry In Helpers.PairUpCommonParentActivities(activities)
                            Dim designer3 As CompositeActivityDesigner = [TryCast](ActivityDesigner.GetDesigner([TryCast](entry.Key,Activity)),CompositeActivityDesigner)
                            If ((Not designer3 Is Nothing) AndAlso Not designer3.CanRemoveActivities(New List([Of] Activity)(DirectCast(DirectCast(entry.Value, ArrayList).ToArray(GetType(Activity)), Activity())).AsReadOnly)) Then
                                flag = False
                            End If
                        Next
                        If flag Then
                            Dim components As New List([Of] ConnectorHitTestInfo)
                            Dim obj2 As Object
                            For Each obj2 In selectedComponents
                                Dim item As ConnectorHitTestInfo = [TryCast](obj2,ConnectorHitTestInfo)
                                If (Not item Is Nothing) Then
                                    components.Add(item)
                                End If
                            Next
                            CompositeActivityDesigner.RemoveActivities(MyBase.ParentView, activities.AsReadOnly, SR.GetString("DeletingActivities"))
                            If ((Not service Is Nothing) AndAlso (components.Count > 0)) Then
                                service.SetSelectedComponents(components, SelectionTypes.Add)
                            End If
                            eventArgs.Handled = True
                        End If
                    End If
                End If
            ElseIf (((eventArgs.KeyCode = Keys.Left) OrElse (eventArgs.KeyCode = Keys.Right)) OrElse (((eventArgs.KeyCode = Keys.Up) OrElse (eventArgs.KeyCode = Keys.Down)) OrElse (eventArgs.KeyCode = Keys.Tab))) Then
                Dim designer4 As ActivityDesigner = ActivityDesigner.GetDesigner([TryCast](service.PrimarySelection,Activity))
                If ((Not designer4 Is Nothing) AndAlso (Not designer4.ParentDesigner Is Nothing)) Then
                    DirectCast(designer4.ParentDesigner, IWorkflowDesignerMessageSink).OnKeyDown(eventArgs)
                    eventArgs.Handled = True
                End If
            End If
            If Not eventArgs.Handled Then
                Dim designerWithFocus As ActivityDesigner = Me.GetDesignerWithFocus
                If (Not designerWithFocus Is Nothing) Then
                    DirectCast(designerWithFocus, IWorkflowDesignerMessageSink).OnKeyDown(eventArgs)
                End If
            End If
            Return eventArgs.Handled
        End Function

        Protected Overrides Function OnKeyUp(ByVal eventArgs As KeyEventArgs) As Boolean
            Dim designerWithFocus As ActivityDesigner = Me.GetDesignerWithFocus
            If (Not designerWithFocus Is Nothing) Then
                DirectCast(designerWithFocus, IWorkflowDesignerMessageSink).OnKeyUp(eventArgs)
            End If
            Return False
        End Function

        Protected Overrides Sub OnLayout(ByVal eventArgs As LayoutEventArgs)
            Dim parentView As WorkflowView = MyBase.ParentView
            [Using] graphics As Graphics = parentView.CreateGraphics
                If (Not parentView.RootDesigner Is Nothing) Then
                    Try 
                        DirectCast(parentView.RootDesigner, IWorkflowDesignerMessageSink).OnLayoutSize(graphics)
                    Catch exception1 As Exception
                    End Try
                    Try 
                        DirectCast(parentView.RootDesigner, IWorkflowDesignerMessageSink).OnLayoutPosition(graphics)
                    Catch exception2 As Exception
                    End Try
                End If
            End [Using]
        End Sub

        Protected Overrides Function OnMouseCaptureChanged() As Boolean
            If (Not Me.currentActiveDesigner Is Nothing) Then
                DirectCast(Me.currentActiveDesigner, IWorkflowDesignerMessageSink).OnMouseCaptureChanged
            End If
            Return False
        End Function

        Protected Overrides Function OnMouseDoubleClick(ByVal eventArgs As MouseEventArgs) As Boolean
            Dim service As ISelectionService = [TryCast](MyBase.GetService(GetType(ISelectionService)),ISelectionService)
            If (Not service Is Nothing) Then
                Dim list As New ArrayList(service.GetSelectedComponents)
                Dim i As Integer
                For i = 0 To list.Count - 1
                    Dim activity As Activity = [TryCast](list.Item(i),Activity)
                    If (Not activity Is Nothing) Then
                        Dim designer As IDesigner = ActivityDesigner.GetDesigner(activity)
                        If (Not designer Is Nothing) Then
                            designer.DoDefaultAction
                            DirectCast(designer, IWorkflowDesignerMessageSink).OnMouseDoubleClick(eventArgs)
                            Exit For
                        End If
                    End If
                Next i
            End If
            Return False
        End Function

        Protected Overrides Function OnMouseDown(ByVal eventArgs As MouseEventArgs) As Boolean
            Dim clientPoint As New Point(eventArgs.X, eventArgs.Y)
            Dim parentView As WorkflowView = MyBase.ParentView
            If Not parentView.IsClientPointInActiveLayout(clientPoint) Then
                Return True
            End If
            Dim activity As Object = Nothing
            Dim messageHitTestContext As HitTestInfo = MyBase.MessageHitTestContext
            If (messageHitTestContext Is HitTestInfo.Nowhere) Then
                activity = parentView.RootDesigner.Activity
            Else
                activity = messageHitTestContext.SelectableObject
            End If
            If (Not activity Is Nothing) Then
                Dim service As ISelectionService = [TryCast](MyBase.GetService(GetType(ISelectionService)),ISelectionService)
                If (Not service Is Nothing) Then
                    service.SetSelectedComponents(New Object() { activity }, SelectionTypes.Click)
                End If
            End If
            If (Not Me.currentActiveDesigner Is messageHitTestContext.AssociatedDesigner) Then
                If (Not Me.currentActiveDesigner Is Nothing) Then
                    DirectCast(Me.currentActiveDesigner, IWorkflowDesignerMessageSink).OnMouseLeave
                End If
                Me.currentActiveDesigner = messageHitTestContext.AssociatedDesigner
                If (Not Me.currentActiveDesigner Is Nothing) Then
                    DirectCast(Me.currentActiveDesigner, IWorkflowDesignerMessageSink).OnMouseEnter(eventArgs)
                End If
            End If
            If ((Not Me.currentActiveDesigner Is Nothing) AndAlso ((Control.ModifierKeys And (Keys.Control Or Keys.Shift)) = Keys.None)) Then
                DirectCast(Me.currentActiveDesigner, IWorkflowDesignerMessageSink).OnMouseDown(eventArgs)
            End If
            Return False
        End Function

        Protected Overrides Function OnMouseEnter(ByVal eventArgs As MouseEventArgs) As Boolean
            If (Not Me.currentActiveDesigner Is Nothing) Then
                DirectCast(Me.currentActiveDesigner, IWorkflowDesignerMessageSink).OnMouseEnter(eventArgs)
            End If
            Return False
        End Function

        Protected Overrides Function OnMouseHover(ByVal eventArgs As MouseEventArgs) As Boolean
            If (Not Me.currentActiveDesigner Is Nothing) Then
                DirectCast(Me.currentActiveDesigner, IWorkflowDesignerMessageSink).OnMouseHover(eventArgs)
            End If
            Return False
        End Function

        Protected Overrides Function OnMouseLeave() As Boolean
            If (Not Me.currentActiveDesigner Is Nothing) Then
                DirectCast(Me.currentActiveDesigner, IWorkflowDesignerMessageSink).OnMouseLeave
                Me.currentActiveDesigner = Nothing
            End If
            Return False
        End Function

        Protected Overrides Function OnMouseMove(ByVal eventArgs As MouseEventArgs) As Boolean
            Dim clientPoint As New Point(eventArgs.X, eventArgs.Y)
            If Not MyBase.ParentView.IsClientPointInActiveLayout(clientPoint) Then
                If (Not Me.currentActiveDesigner Is Nothing) Then
                    DirectCast(Me.currentActiveDesigner, IWorkflowDesignerMessageSink).OnMouseLeave
                End If
                Me.currentActiveDesigner = Nothing
                Return True
            End If
            Dim messageHitTestContext As HitTestInfo = MyBase.MessageHitTestContext
            If (Not Me.currentActiveDesigner Is messageHitTestContext.AssociatedDesigner) Then
                If (Not Me.currentActiveDesigner Is Nothing) Then
                    DirectCast(Me.currentActiveDesigner, IWorkflowDesignerMessageSink).OnMouseLeave
                End If
                Me.currentActiveDesigner = messageHitTestContext.AssociatedDesigner
                If (Not Me.currentActiveDesigner Is Nothing) Then
                    DirectCast(Me.currentActiveDesigner, IWorkflowDesignerMessageSink).OnMouseEnter(eventArgs)
                End If
            ElseIf (Not Me.currentActiveDesigner Is Nothing) Then
                DirectCast(Me.currentActiveDesigner, IWorkflowDesignerMessageSink).OnMouseMove(eventArgs)
            End If
            Return False
        End Function

        Protected Overrides Function OnMouseUp(ByVal eventArgs As MouseEventArgs) As Boolean
            Dim clientPoint As New Point(eventArgs.X, eventArgs.Y)
            If Not MyBase.ParentView.IsClientPointInActiveLayout(clientPoint) Then
                If (Not Me.currentActiveDesigner Is Nothing) Then
                    DirectCast(Me.currentActiveDesigner, IWorkflowDesignerMessageSink).OnMouseLeave
                End If
                Me.currentActiveDesigner = Nothing
                Return True
            End If
            Dim messageHitTestContext As HitTestInfo = MyBase.MessageHitTestContext
            If (Not Me.currentActiveDesigner Is messageHitTestContext.AssociatedDesigner) Then
                If (Not Me.currentActiveDesigner Is Nothing) Then
                    DirectCast(Me.currentActiveDesigner, IWorkflowDesignerMessageSink).OnMouseLeave
                End If
                Me.currentActiveDesigner = messageHitTestContext.AssociatedDesigner
                If (Not Me.currentActiveDesigner Is Nothing) Then
                    DirectCast(Me.currentActiveDesigner, IWorkflowDesignerMessageSink).OnMouseEnter(eventArgs)
                End If
            End If
            If (Not Me.currentActiveDesigner Is Nothing) Then
                DirectCast(Me.currentActiveDesigner, IWorkflowDesignerMessageSink).OnMouseUp(eventArgs)
            End If
            Return False
        End Function

        Protected Overrides Function OnMouseWheel(ByVal eventArgs As MouseEventArgs) As Boolean
            Me.UpdateViewOnMouseWheel(eventArgs, Control.ModifierKeys)
            Return True
        End Function

        Protected Overrides Function OnScroll(ByVal sender As ScrollBar, ByVal value As Integer) As Boolean
            Dim designerWithFocus As ActivityDesigner = Me.GetDesignerWithFocus
            If (Not designerWithFocus Is Nothing) Then
                DirectCast(designerWithFocus, IWorkflowDesignerMessageSink).OnScroll(sender, value)
            End If
            Return False
        End Function

        Protected Overrides Function OnShowContextMenu(ByVal screenMenuPoint As Point) As Boolean
            Dim service As IMenuCommandService = [TryCast](MyBase.GetService(GetType(IMenuCommandService)),IMenuCommandService)
            If (Not service Is Nothing) Then
                service.ShowContextMenu(WorkflowMenuCommands.SelectionMenu, screenMenuPoint.X, screenMenuPoint.Y)
            End If
            Return True
        End Function

        Protected Overrides Sub OnThemeChange()
            Dim parentView As WorkflowView = MyBase.ParentView
            If (Not parentView.RootDesigner Is Nothing) Then
                DirectCast(parentView.RootDesigner, IWorkflowDesignerMessageSink).OnThemeChange
            End If
        End Sub

        Protected Overrides Function ProcessMessage(ByVal message As Message) As Boolean
            Dim designerWithFocus As ActivityDesigner = Me.GetDesignerWithFocus
            If (Not designerWithFocus Is Nothing) Then
                DirectCast(designerWithFocus, IWorkflowDesignerMessageSink).ProcessMessage(message)
            End If
            Return False
        End Function

        Private Sub UpdateViewOnMouseWheel(ByVal eventArgs As MouseEventArgs, ByVal modifierKeys As Keys)
            Dim parentView As WorkflowView = MyBase.ParentView
            If (Control.ModifierKeys = Keys.Control) Then
                Dim num As Integer = (parentView.Zoom + ((eventArgs.Delta / 120) * 10))
                num = Math.Min(Math.Max(num, 10), 400)
                parentView.Zoom = num
            Else
                Dim num2 As Integer = (-eventArgs.Delta / 120)
                Dim smallChange As Integer = parentView.VScrollBar.SmallChange
                Dim scrollPosition As Point = parentView.ScrollPosition
                scrollPosition.Y = (scrollPosition.Y + (num2 * smallChange))
                parentView.ScrollPosition = scrollPosition
            End If
        End Sub

        Private Sub UpdateViewOnPageUpDown(ByVal pageUp As Boolean)
            Dim parentView As WorkflowView = MyBase.ParentView
            Dim scrollPosition As Point = parentView.ScrollPosition
            scrollPosition.Y = (scrollPosition.Y + (If(pageUp, -1, 1) * parentView.VScrollBar.LargeChange))
            parentView.ScrollPosition = scrollPosition
        End Sub


        ' Fields
        Private currentActiveDesigner As ActivityDesigner
    End Class
End Namespace

